<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>CancelToken</title>
  </head>
  <body>
    <button>send</button>
    <button>cancel</button>

    <script>
      function Axios(config) {
        this.defaults = config;
      }
      Axios.prototype.request = function (config) {
        return dispatchRequest(config);
      };

      function dispatchRequest(config) {
        return adapter(config).then(
          (response) => {
            return response;
          },
          (error) => {
            Promise.reject(error);
          }
        );
      }

      function adapter(config) {
        return new Promise((resolve, reject) => {
          let xhr = new XMLHttpRequest();
          xhr.open(config.method, config.url);
          xhr.send();
          xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
              if (xhr.status >= 200 && xhr.status < 300) {
                resolve({
                  data: xhr.responseText,
                  status: xhr.status,
                  statusText: xhr.statusText,
                });
              } else {
                reject(new Error("请求失败"));
              }
            }
          };
          if (config.cancelToken) {
            config.cancelToken.promise.then(function onCanceled(cancel) {
              xhr.abort();
              reject(cancel);
            });
          }
        });
      }

      function cancelToken(executor) {
        let promisevar;
        this.promise = new Promise((resolve) => {
          promisevar = resolve;
        });

        let token = this;
        executor(function cancel(message) {
          token.reason = message;
          promisevar(token.reason);
        });
      }

      // ==========================
      let context = new Axios({});
      let axios = Axios.prototype.request.bind(context);
      let cancel = null;

      let obtns = document.querySelectorAll("button");

      obtns[0].onclick = function () {
        if (cancel != null) {
          cancel();
        }
        axios({
          method: "get",
          // url: "https://yesno.wtf/api",
          url: "http://localhost:3000/posts",
          cancelToken: new cancelToken(function (c) {
            cancel = c;
            console.log(c);
          }),
        }).then((res) => {
          console.log(res);
        });
      };

      obtns[1].onclick = function () {
        cancel();
      };
    </script>
  </body>
</html>
